package com.atguigu.daijia.driver.service.impl;

import com.atguigu.daijia.common.execption.GuiguException;
import com.atguigu.daijia.common.result.ResultCodeEnum;
import com.atguigu.daijia.driver.config.TencentCloudProperties;
import com.atguigu.daijia.driver.service.CosService;
import com.atguigu.daijia.driver.service.OcrService;
import com.atguigu.daijia.model.vo.driver.CosUploadVo;
import com.atguigu.daijia.model.vo.driver.DriverLicenseOcrVo;
import com.atguigu.daijia.model.vo.driver.IdCardOcrVo;
import com.qcloud.cos.utils.Base64;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.ocr.v20181119.OcrClient;
import com.tencentcloudapi.ocr.v20181119.models.DriverLicenseOCRRequest;
import com.tencentcloudapi.ocr.v20181119.models.DriverLicenseOCRResponse;
import com.tencentcloudapi.ocr.v20181119.models.IDCardOCRRequest;
import com.tencentcloudapi.ocr.v20181119.models.IDCardOCRResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.format.DateTimeFormat;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

@Slf4j
@Service
@SuppressWarnings({"unchecked", "rawtypes"})
@RequiredArgsConstructor
public class OcrServiceImpl implements OcrService {

    private final CosService cosService;
    private final TencentCloudProperties tencentCloudProperties;

    /**
     * 身份证上传和识别
     * @param file
     * @return
     */
    @Override
    public IdCardOcrVo idCardOcr(MultipartFile file) {
        IDCardOCRResponse idCardOCRResponse = null;
        try {
            // 将身份证图片转为 Base64 字符串
            String idCardBase64 = Base64.encodeAsString(file.getBytes());

            // 调用腾讯云身份证识别接口
            // 实例化一个认证对象
            Credential credential = new Credential(tencentCloudProperties.getSecretId(), tencentCloudProperties.getSecretKey());
            // 实例化一个 http 选项，可选的，没有特殊需求可以跳过
            HttpProfile httpProfile = new HttpProfile();
            httpProfile.setEndpoint("ocr.tencentcloudapi.com");
            // 实例化一个 client 选项，可选的，没有特殊需求可以跳过
            ClientProfile clientProfile = new ClientProfile();
            clientProfile.setHttpProfile(httpProfile);
            // 实例化要请求产品的 client 对象，clientProfile 是可选的
            OcrClient ocrClient = new OcrClient(credential, tencentCloudProperties.getRegion(), clientProfile);
            // 实例化一个请求对象，每个接口都会对应一个 request 对象
            IDCardOCRRequest idCardOCRRequest = new IDCardOCRRequest();
            // 请求对象中传入身份证图片的 Base64 编码
            idCardOCRRequest.setImageBase64(idCardBase64);
            // 返回的结果是一个 IDCardOCRResponse 的实例，与请求对象对应
            idCardOCRResponse = ocrClient.IDCardOCR(idCardOCRRequest);
        } catch (Exception e) {
            e.printStackTrace();
            throw new GuiguException(ResultCodeEnum.IDCARD_OCR_FAIL);
        }

        // 封装 IdCardOcrVo 对象并返回
        IdCardOcrVo idCardOcrVo = new IdCardOcrVo();
        if (StringUtils.hasText(idCardOCRResponse.getName())) {
            // OCR 识别结果包含 name 字段，说明是身份证正面（人像面）
            idCardOcrVo.setName(idCardOCRResponse.getName());
            // 性别，字符串类型，1-男 2-女
            idCardOcrVo.setGender("男".equals(idCardOCRResponse.getSex()) ? "1" : "2");
            // 生日，Date 类型
            idCardOcrVo.setBirthday(DateTimeFormat.forPattern("yyyy/MM/dd").parseDateTime(idCardOCRResponse.getBirth()).toDate());
            // 身份证号码
            idCardOcrVo.setIdcardNo(idCardOCRResponse.getIdNum());
            // 身份证地址
            idCardOcrVo.setIdcardAddress(idCardOCRResponse.getAddress());

            // 上传身份证正面图片到腾讯云 COS
            CosUploadVo idCardFront = cosService.upload(file, "idCard");
            // 设置身份证正面图片地址
            idCardOcrVo.setIdcardFrontUrl(idCardFront.getUrl());
            // 设置身份证正面图片临时回显地址
            idCardOcrVo.setIdcardFrontShowUrl(idCardFront.getShowUrl());
        } else {
            // OCR 识别结果不包含 name 字段，说明是身份证反面（国徽面）
            // 设置身份证过期时间，OCR 识别身份证有效期间格式是 2010.07.21-2020.07.21，只需要取截止日期即可
            String IdCardExpire = idCardOCRResponse.getValidDate().split("-")[1];
            idCardOcrVo.setIdcardExpire(DateTimeFormat.forPattern("yyyy.MM.dd").parseDateTime(IdCardExpire).toDate());
            // 上传身份证反面图片到腾讯云 COS
            CosUploadVo idCardBack = cosService.upload(file, "idCard");
            // 设置身份证反面图片地址
            idCardOcrVo.setIdcardBackUrl(idCardBack.getUrl());
            // 设置身份证反面图片临时回显地址
            idCardOcrVo.setIdcardBackShowUrl(idCardBack.getShowUrl());
        }
        return idCardOcrVo;
    }

    /**
     * 驾驶证上传和识别
     * @param file
     * @return
     */
    @Override
    public DriverLicenseOcrVo driverLicenseOcr(MultipartFile file) {
        DriverLicenseOCRResponse ocrResponse = null;
        try {
            // 将驾驶证图片转为 Base64 字符串
            String driverLicenseBase64 = Base64.encodeAsString(file.getBytes());

            // 实例化一个认证对象
            Credential credential = new Credential(tencentCloudProperties.getSecretId(), tencentCloudProperties.getSecretKey());
            // 实例化一个 http 选项，可选的，没有特殊需求可以跳过
            HttpProfile httpProfile = new HttpProfile();
            httpProfile.setEndpoint("ocr.tencentcloudapi.com");
            // 实例化一个 client 选项，可选的，没有特殊需求可以跳过
            ClientProfile clientProfile = new ClientProfile();
            clientProfile.setHttpProfile(httpProfile);
            // 实例化要请求产品的 client 对象，clientProfile 是可选的
            DriverLicenseOCRRequest driverLicenseOCRRequest = new DriverLicenseOCRRequest();
            OcrClient ocrClient = new OcrClient(credential, tencentCloudProperties.getRegion(), clientProfile);
            // 请求对象中传入驾驶证图片的 Base64 编码
            driverLicenseOCRRequest.setImageBase64(driverLicenseBase64);
            // 返回的结果是一个 DriverLicenseOCRResponse 的实例，与请求对象对应
            ocrResponse = ocrClient.DriverLicenseOCR(driverLicenseOCRRequest);
        } catch (Exception e) {
            e.printStackTrace();
            throw new GuiguException(ResultCodeEnum.DRIVER_LICENSE_OCR_FAIL);
        }

        // 封装 DriverLicenseOcrVo 对象并返回
        DriverLicenseOcrVo driverLicenseOcrVo = new DriverLicenseOcrVo();
        if (StringUtils.hasText(ocrResponse.getName())) {
            // OCR 识别结果包含 name 字段，说明是驾驶证正页
            // 姓名
            driverLicenseOcrVo.setName(ocrResponse.getName());
            // 准驾车型
            driverLicenseOcrVo.setDriverLicenseClazz(ocrResponse.getClass_());
            // 驾驶证号码
            driverLicenseOcrVo.setDriverLicenseNo(ocrResponse.getCardCode());
            // 初次领证日期
            driverLicenseOcrVo.setDriverLicenseIssueDate(DateTimeFormat.forPattern("yyyy-MM-dd").parseDateTime(ocrResponse.getDateOfFirstIssue()).toDate());
            // 有效期
            driverLicenseOcrVo.setDriverLicenseExpire(DateTimeFormat.forPattern("yyyy-MM-dd").parseDateTime(ocrResponse.getEndDate()).toDate());
            // 上传驾驶证正页图片到腾讯云 COS
            CosUploadVo driverLicenseFront = cosService.upload(file, "driverLicense");
            // 设置驾驶证正页图片地址
            driverLicenseOcrVo.setDriverLicenseFrontUrl(driverLicenseFront.getUrl());
            // 设置驾驶证正页图片临时回显地址
            driverLicenseOcrVo.setDriverLicenseFrontShowUrl(driverLicenseFront.getShowUrl());
        } else {
            // OCR 识别结果不包含 name 字段，说明是驾驶证副页
            // 上传驾驶证副页图片到腾讯云 COS
            CosUploadVo driverLicenseBack = cosService.upload(file, "driverLicense");
            // 设置驾驶证副页图片地址
            driverLicenseOcrVo.setDriverLicenseBackUrl(driverLicenseBack.getUrl());
            // 设置驾驶证副页图片临时回显地址
            driverLicenseOcrVo.setDriverLicenseBackShowUrl(driverLicenseBack.getShowUrl());
        }
        return driverLicenseOcrVo;
    }
}
